package ch.dreamweb.readpractice.client.lesetraining.test.presenter;

import ch.dreamweb.readpractice.client.lesetraining.Constants.Test;
import ch.dreamweb.readpractice.client.lesetraining.meta.event.StartLoginEvent;
import ch.dreamweb.readpractice.client.lesetraining.meta.presenter.Presenter;
import ch.dreamweb.readpractice.client.lesetraining.test.event.StartTest1Event;
import ch.dreamweb.readpractice.client.lesetraining.test.event.StartTest2Event;
import ch.dreamweb.readpractice.client.lesetraining.test.event.StartTest3Event;
import ch.dreamweb.readpractice.client.lesetraining.test.event.StartTest4Event;
import ch.dreamweb.readpractice.client.lesetraining.test.event.StartTest5Event;
import ch.dreamweb.readpractice.client.lesetraining.test.event.StartTest6Event;
import ch.dreamweb.readpractice.client.lesetraining.test.view.MetaTestView;
import ch.dreamweb.readpractice.client.managed.request.ApplicationRequestFactory;
import ch.dreamweb.readpractice.client.managed.request.SettingProxy;
import ch.dreamweb.readpractice.client.managed.request.SettingRequest;
import ch.dreamweb.readpractice.shared.InfoHolder;

import com.allen_sauer.gwt.log.client.Log;
import com.allen_sauer.gwt.voices.client.Sound;
import com.allen_sauer.gwt.voices.client.SoundController;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.requestfactory.shared.Receiver;
import com.google.gwt.requestfactory.shared.Request;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.RootPanel;

public class MetaTestPresenter implements Presenter, MetaTestView.Presenter {

	private final EventBus eventBus;
	private final MetaTestView view;
	private final InfoHolder info = InfoHolder.getInstance();
	private final ApplicationRequestFactory requests;
	private SettingRequest settingRequest;
	private SettingProxy editableSetting;
	protected SoundController soundController = new SoundController();

	public MetaTestPresenter(EventBus eventBus,
			ApplicationRequestFactory requests, MetaTestView view) {
		this.eventBus = eventBus;
		this.requests = requests;
		this.view = view;
		this.view.setPresenter(this);
		init();
	}

	protected void init() {
		settingRequest = requests.settingRequest();
		editableSetting = settingRequest.edit(info.getSetting());
		view.setLabelHead(editableSetting.getTestday(),
				editableSetting.getLogin());
		showUnitsAndMenu();
	}

	protected void updateSetting(Long id) {
		RootPanel.get("loading").setVisible(true);
		settingRequest = requests.settingRequest();
		settingRequest.findSetting(id).fire(new Receiver<SettingProxy>() {
			@Override
			public void onSuccess(SettingProxy setting) {
				RootPanel.get("loading").setVisible(false);
				Log.debug("Getting setting: " + setting);
				info.setSetting(setting);
				init();
			}
		});
	}

	@Override
	public void go(final HasWidgets container) {
		container.clear();
		container.add(view.asWidget());
		if (info.getSettingId() != null) {
			init();
		} else {
			// go back to login
			eventBus.fireEvent(new StartLoginEvent());
		}

	}

	private void showUnitsAndMenu() {
		Log.info("Enter ShowUnitAndMenu, Testnumber: "
				+ editableSetting.getTestnumber());
		int testnumber;
		int testround;
		testnumber = editableSetting.getTestnumber();
		info.setTestround(editableSetting.getTestround());

		if ((testnumber >= 7) || (testnumber < 1)
				|| (!editableSetting.getEnabletest())) {

			editableSetting.setEnabletest(false);
			editableSetting.setTestnumber(1);
			editableSetting.setTestround(info.getTestround() + 1);

			view.setLogoutVisible(true);
			Request<Void> updateReq = settingRequest.persist().using(
					editableSetting);
			Log.debug("updateReq. id=" + editableSetting.getId() + ", login="
					+ editableSetting.getLogin());
			updateReq.fire(new Receiver() {
				@Override
				public void onSuccess(Object response) {
					Log.debug("update success: " + editableSetting);
					info.setSetting(editableSetting);
				}
			});
		} else {
			view.setLogoutVisible(false);
		}

		view.setTestVisible(Test.ALL, true);
		view.setTestEnabled(Test.ALL, false);
		switch (testnumber) {
		case 1: {
			view.setTestEnabled(Test.TEST1, true);
			break;
		}
		case 2: {
			view.setTestEnabled(Test.TEST2, true);
			break;
		}
		case 3: {
			view.setTestEnabled(Test.TEST3, true);
			break;
		}
		case 4: {
			view.setTestEnabled(Test.TEST4, true);
			break;
		}
		case 5: {
			view.setTestEnabled(Test.TEST5, true);
			break;
		}
		case 6: {
			view.setTestEnabled(Test.TEST6, true);
			break;
		}
		default: {
			view.setTestEnabled(Test.ALL, false);
			view.setLogoutVisible(true);
		}
		}

		Log.info("Exit ShowUnitAndMenu, Testnumber: "
				+ editableSetting.getTestnumber());

	}

	@Override
	public void onTestButtonClicked(Test test) {
		switch (test) {
		case TEST1:
			Log.info("Starting Test 1");
			info.setTestActive(1);
			eventBus.fireEvent(new StartTest1Event());
			break;
		case TEST2:
			Log.info("Starting Test 2");
			info.setTestActive(2);
			eventBus.fireEvent(new StartTest2Event());
			break;
		case TEST3:
			Log.info("Starting Test 3");
			info.setTestActive(3);
			eventBus.fireEvent(new StartTest3Event());
			break;
		case TEST4:
			Log.info("Starting Test 4");
			info.setTestActive(4);
			eventBus.fireEvent(new StartTest4Event());
			break;
		case TEST5:
			Log.info("Starting Test 5");
			info.setTestActive(5);
			eventBus.fireEvent(new StartTest5Event());
			break;
		case TEST6:
			Log.info("Starting Test 6");
			info.setTestActive(6);
			eventBus.fireEvent(new StartTest6Event());
			break;
		case SOUNDTEST:
			Log.info("Soundtest");
			playTestsound();
			// Muss aktiviert werden, weil in seltenen Fällen das Auslesen aus
			// Setting nicht richtig geklappt hat.
			init();
			break;
		default:
			// should not happen
			return;
		}
	}

	@Override
	public EventBus getEventBus() {
		return eventBus;
	}

	@Override
	public void onLogoutButtonClicked() {
		info.setOnLogoutButtonClicked(true);
		info.setSettingId(null);
		eventBus.fireEvent(new StartLoginEvent());
	}

	@SuppressWarnings("deprecation")
	public void playTestsound() {
		String soundfileformat = "mp3";
		try {
			soundfileformat = editableSetting.getSoundfiletype();
			if ((soundfileformat.equals("bas"))
					|| (soundfileformat.equals("mp3"))
					|| (soundfileformat.equals("mp4"))
					// || (soundfileformat.equals("mpeg"))
					|| (soundfileformat.equals("ogg"))) {
				Log.info("Soundfileformat is set from Setting as "
						+ soundfileformat);
			} else {
				soundfileformat = "mp3";
				Log.info("Soundfileformat is set default as " + soundfileformat);

			}

		} catch (Exception e) {
			soundfileformat = "mp3";
			editableSetting.setSoundfiletype("mp3");
			Log.info("Soundfileformat is set default as " + soundfileformat);
			// TODO: handle exception
		}

		if (soundfileformat.equals("bas")) {
			final Sound soundTest = soundController.createSound(
					Sound.MIME_TYPE_AUDIO_BASIC, "sounds/feedback/test.mp3");
			soundTest.play();
		} else if (soundfileformat.equals("mp3")) {
			final Sound soundTest = soundController.createSound(
					Sound.MIME_TYPE_AUDIO_MPEG_MP3, "sounds/feedback/test."
							+ soundfileformat);
			soundTest.play();
		} else if (soundfileformat.equals("mp4")) {
			final Sound soundTest = soundController.createSound(
					Sound.MIME_TYPE_AUDIO_MP4, "sounds/feedback/test."
							+ soundfileformat);
			soundTest.play();
		} else if (soundfileformat.equals("mpeg")) {
			final Sound soundTest = soundController.createSound(
					Sound.MIME_TYPE_AUDIO_MPEG, "sounds/feedback/test."
							+ soundfileformat);
			soundTest.play();
		} else if (soundfileformat.equals("ogg")) {
			final Sound soundTest = soundController.createSound(
					Sound.MIME_TYPE_AUDIO_OGG_VORBIS, "sounds/feedback/test."
							+ soundfileformat);
			soundTest.play();
		}

		else {
			final Sound soundTest = soundController.createSound(
					Sound.MIME_TYPE_AUDIO_MPEG_MP3, "sounds/feedback/test."
							+ soundfileformat);
			soundTest.play();
		}

	}

	{

	}

}
